feat: Vis.to_gltf() / .to_threejs() / .export_mtlx() method sugar#79
Merged
feat: Vis.to_gltf() / .to_threejs() / .export_mtlx() method sugar#79
Conversation
Add method-form discoverability on Vis without touching the architectural separation that keeps adapters as pure module-level transformations. Drop-in: method and module-level produce identical output; the existing pymat.vis.to_gltf(material) call site stays untouched. - Adapters become polymorphic: to_gltf / to_threejs / export_mtlx accept either a Material or a standalone Vis (duck-typed via the .vis attribute). Backward-compatible for all existing call sites. - New Vis methods delegate to the module-level functions — zero logic duplication, no back-reference from Vis to Material. - Vis.to_gltf(name=...) / .export_mtlx(name=...) let callers on a standalone Vis set the name explicitly; the module-level form on a Material auto-populates from material.name as before. Tests: - TestAdapterPolymorphism pins (module fn vs Material) == (Vis form). - TestVisAdapterMethods pins (m.vis.method == module_fn(m)). - Drop-in claim also holds for the e2e path (test_e2e_vis.py's existing to_threejs tests unchanged and still green). Related: build123d#1270 (downstream consumer motivating the discoverability push), mat-vis#93 (architecturally-cleaner VisAsset payload object proposal — this issue's methods become one-line forwards to VisAsset.to_* once that lands). Also folds in two test-claim-backfills from the build123d#1270 comment draft: - tests/test_e2e_vis.py::test_mtlx_xml_returns_materialx_string - tests/test_integration.py::TestGltfMaterialPassthrough (pins the real behavior: apply_to preserves base-color only; direct shape.material doesn't reach export_gltf at all today — the gap that build123d#1270 closes).
Gaps the previous commit left open: - Detached-Vis path (no owning Material) was never exercised — only Material-wrapped Vis. Every adapter now has a detached-Vis test. - Duck-typing invariant ``hasattr(vis, "vis") is False`` was implicit. Pinned so a future refactor can't silently break ``_resolve_vis_and_name``. - ``to_gltf(obj, name=...)`` keyword-only contract was untested. Added a positional-call TypeError test. - Method surface (``hasattr(v, "to_gltf")`` etc.) wasn't asserted separately — now a dedicated test. - ``export_mtlx(vis, out)`` without ``name=`` had no pin — added. - Trimmed a redundant assertion (``"Stem" in stem or stem == "Stem"``).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds method-form discoverability on
Visfor the output adapters.m.vis.<TAB>now surfacesto_gltf(),to_threejs(),export_mtlx(). Zero architectural change — methods are thin delegates to the existing module-level functions, which remain the source of truth.Drop-in for end users:
pymat.vis.to_gltf(material)continues to work exactly as before. No deprecation, no breaking change, no caller churn.Closes #78. Complements mat-vis#93 (the architecturally-cleaner
VisAssetproposal — once that lands, these methods become one-line forwards toself._asset.to_gltf()).What changed
pymat.vis.adapters—to_gltf,to_threejs,export_mtlxaccept either aMaterialor aVis(duck-typed via.vis). Backward-compatible for all existing call sites.pymat.vis._model.Vis— newto_threejs(),to_gltf(*, name=None),export_mtlx(out, *, name=None)methods delegating to the module-level functions. No logic duplication.Vis → Materialcoupling.Tests
tests/test_adapters.py::TestAdapterPolymorphism—to_*(m) == to_*(m.vis).tests/test_adapters.py::TestVisAdapterMethods—m.vis.to_*() == to_*(m).tests/test_adapters.py::TestAdapterOnDetachedVis— full adapter path on aVis()constructed with no owning Material.name=signature, and method-surface discoverability each pinned by a dedicated test.test_e2e_vis.py::test_mtlx_xml_returns_materialx_string.test_integration.py::TestGltfMaterialPassthrough— pins the real build123d glTF behavior (apply_to preserves base color only; directshape.materialdoesn't reach the exporter), documenting the gap that build123d#1270 closes.Test plan
299 passed, 18 skipped.Out of scope
VisAssetin mat-vis-client): separate issue mat-vis#93, needs design conversation with the build123d consumer.